package com.streamkar.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.streamkar.common.es.ExecuteDslComponent;
import com.streamkar.constant.Constants;
import com.streamkar.entity.domain.Agency;
import com.streamkar.service.AgencyService;
import com.streamkar.util.EsUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName AgencyServiceImpl
 * @Description
 * @Author tyfrost
 * @Date 2018/11/14 上午12:12
 * @Version 1.0
 */
@Service
public class AgencyServiceImpl implements AgencyService {
    private static final Logger LOGGER = LoggerFactory.getLogger(AgencyServiceImpl.class);

    @Autowired
    ExecuteDslComponent executeDslComponent;

    @Autowired
    EsUtil esUtil;

    @Override
    public JSONArray agencyList(Agency agency, String queryValue) {
        String dsl = "{\"_source\":[\"agencyId\",\"country\",\"name\",\"ownerId\",\"ownerName\",\"ownerAvatar\",\"talentCount\",\"activeTalents\",\"newTalents\",\"broadcastTime\",\"totalDiamonds\",\"registerTime\",\"createTime\",\"updateTime\"],\"query\":{\"bool\":{}},\"from\":\"{{offset}}\",\"size\":\"{{limit}}\",\"sort\":[{\"{{orderBy}}\":{\"order\":\"{{orderByType}}\"}}]}";
        Map<String, String> paramMap = new HashMap<>();

        if (StringUtils.isNotBlank(queryValue)) {
            Map<String, Object> queryValueMap = new HashMap<>();
            try {
                Long agencyId = Long.valueOf(queryValue);
                queryValueMap.put("agencyId", agencyId);
            } catch (Exception e) {
                LOGGER.info("queryValue can not parse to Long,agencyId set empty");
            }
            queryValueMap.put("name", queryValue);
            dsl = esUtil.bulidShouldDsl(dsl, queryValueMap);
        }

        paramMap.put("offset", String.valueOf(agency.getOffset()));
        paramMap.put("limit", String.valueOf(agency.getLimit()));
        paramMap.put("orderBy", agency.getOrderBy());
        paramMap.put("orderByType", agency.getOrderByType());
        JSONArray jsonArray = executeDslComponent.executeDsl(Constants.INDEX_AGENCY, dsl, paramMap);
        return jsonArray;
    }

    @Override
    public Agency agencyInfo(Integer agencyId) {
        Agency agency = null;
        if (null == agencyId) {
            LOGGER.error("agencyId is null,return null");
            return agency;
        }

        String dsl = "{\"_source\":[\"agencyId\",\"country\",\"name\",\"ownerId\",\"ownerName\",\"ownerAvatar\",\"talentCount\",\"activeTalents\",\"newTalents\",\"broadcastTime\",\"totalDiamonds\",\"registerTime\",\"createTime\",\"updateTime\"],\"query\":{\"bool\":{\"must\":[{\"term\":{\"agencyId\":{{agencyId}}}}]}}}";
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("agencyId", String.valueOf(agencyId));
        JSONArray jsonArray = executeDslComponent.executeDsl(Constants.INDEX_AGENCY, dsl, paramMap);
        if (!CollectionUtils.isEmpty(jsonArray)) {
            agency = jsonArray.getObject(0, Agency.class);
        }
        return agency;
    }

    @Override
    public JSONArray agencyStat(Integer agencyId) {
        if (null == agencyId) {
            LOGGER.error("agencyId is null,return null");
            return new JSONArray();
        }
        String dsl = "{\"_source\":[\"id\",\"agencyId\",\"country\",\"date\",\"talentCount\",\"activeTalents\",\"newTalents\",\"broadcastTime\",\"totalDiamonds\",\"updateTime\"],\"query\":{\"bool\":{\"must\":[{\"term\":{\"agencyId\":{{agencyId}}}},{\"range\":{\"date\":{\"lte\":\"{{endTime}}\",\"gte\":\"{{startTime}}\",\"time_zone\":\"+08:00\"}}}]}},\"sort\":[{\"date\":{\"order\":\"asc\"}}]}";
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("agencyId", String.valueOf(agencyId));
        // 当前月
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = Calendar.getInstance();
        paramMap.put("endTime", sdf.format(calendar.getTime()));
        // 统计前几个月的数据
        calendar.add(Calendar.MONTH, Constants.STAT_MONTH);
        paramMap.put("startTime", sdf.format(calendar.getTime()));
        JSONArray jsonArray = executeDslComponent.executeDsl(Constants.INDEX_AGENCY_STAT, dsl, paramMap);
        return jsonArray;
    }


    @Override
    public JSONArray agencyHome() {
        JSONArray newArray = new JSONArray();
        String dsl = "{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"range\":{\"date\":{\"gte\":\"{{startTime}}\",\"lte\":\"{{endTime}}\",\"time_zone\":\"+08:00\"}}}]}},\"aggs\":{\"date\":{\"terms\":{\"field\":\"date\",\"order\":[{\"_term\":\"asc\"}]},\"aggs\":{\"totalDiamonds\":{\"sum\":{\"field\":\"totalDiamonds\"}},\"activeTalents\":{\"sum\":{\"field\":\"activeTalents\"}},\"newTalents\":{\"sum\":{\"field\":\"newTalents\"}},\"talentCount\":{\"sum\":{\"field\":\"talentCount\"}},\"agencyCount\":{\"cardinality\":{\"field\":\"agencyId\"}}}}}}";
        Map<String, String> paramMap = new HashMap<>();
        // 当前月
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = Calendar.getInstance();
        paramMap.put("endTime", sdf.format(calendar.getTime()));
        // 统计前几个月的数据
        calendar.add(Calendar.MONTH, Constants.STAT_MONTH);
        paramMap.put("startTime", sdf.format(calendar.getTime()));
        try {
            JSONObject jsonObject = executeDslComponent.searchData(Constants.INDEX_AGENCY_STAT, dsl, paramMap);
            if (null != jsonObject && null != jsonObject.getJSONObject("date")) {
                JSONArray buckets = jsonObject.getJSONObject("date").getJSONArray("buckets");
                if (!CollectionUtils.isEmpty(buckets)) {
                    for (Object tempObj : buckets) {
                        JSONObject tempJson = (JSONObject) tempObj;
                        JSONObject newJson = new JSONObject();
                        for (Map.Entry<String, Object> keyValue : tempJson.entrySet()) {
                            if (keyValue.getValue() instanceof JSONObject) {
                                newJson.put(keyValue.getKey(), ((JSONObject) keyValue.getValue()).getLongValue("value"));
                            } else {
                                newJson.put(keyValue.getKey(), keyValue.getValue());
                            }
                        }
                        newArray.add(newJson);
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("search agency stat catch an exception", e);
        }
        return newArray;
    }

    @Override
    public JSONObject agencyQuota(Integer agencyId) {
        JSONObject jsonObject = new JSONObject();
        String dsl = "{\"query\":{\"bool\":{\"must\":[{\"term\":{\"agencyId\":\"{{agencyId}}\"}},{\"range\":{\"talentLevel\":{\"gte\":\"1\",\"lte\":\"56\"}}}]}},\"size\":0,\"aggs\":{\"more60H\":{\"sum\":{\"script\":{\"inline\":\"if(doc['broadcastTime'].value >= 3600) return 1;else return 0;\"}}},\"less500KD\":{\"sum\":{\"script\":{\"inline\":\"if(doc['totalDiamonds'].value <= 500000 && doc['broadcastTime'].value > 0) return 1;else return 0;\"}}}}}";
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("agencyId", String.valueOf(agencyId));
        try {
            jsonObject = executeDslComponent.searchData(Constants.INDEX_TALENT, dsl, paramMap);

            // 查询新增主播直播时长大于60小时的数据
            dsl = "{\"query\":{\"bool\":{\"must\":[{\"term\":{\"agencyId\":\"{{agencyId}}\"}},{\"range\":{\"talentLevel\":{\"gte\":\"1\",\"lte\":\"56\"}}},{\"range\":{\"joinTime\":{\"gte\":\"{{startTime}}\"}}}]}},\"size\":0,\"aggs\":{\"more60Hnew\":{\"sum\":{\"script\":{\"inline\":\"if(doc['broadcastTime'].value >= 3600) return 1;else return 0;\"}}}}}";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
            paramMap.put("startTime", sdf.format(calendar.getTime()));
            JSONObject newJsonObject = executeDslComponent.searchData(Constants.INDEX_TALENT, dsl, paramMap);
            if (null != newJsonObject) {
                jsonObject.put("more60Hnew", newJsonObject.get("more60Hnew"));
            }
        } catch (Exception e) {
            LOGGER.error("search agency quota catch an exception", e);
        }
        return jsonObject;
    }
}
